<?php

namespace App\Containers\AppSection\Moneybox\Actions;

use App\Containers\AppSection\Moneybox\Tasks\CreateMoneyboxInTask;
use App\Containers\AppSection\Moneybox\Tasks\GenerateUuidAndIdTask;
use App\Containers\AppSection\Moneybox\Tasks\UpdateMoneyboxInTask;
use App\Containers\AppSection\Profile\Tasks\FindProfileByIdTask;
use App\Containers\AppSection\Project\Tasks\FindProjectByIdTask;
use App\Ship\Exceptions\CreateResourceFailedException;
use App\Ship\Parents\Actions\Action;
use App\Ship\Parents\Requests\Request;
use Exception;

class IdentificationAction extends Action
{
    /**
     * @throws CreateResourceFailedException
     * @throws Exception
     */
    public function run(Request $request)
    {
        $moneyboxIn = app(CreateMoneyboxInTask::class)->run([
            "transaction_uid" => $request->getInputByKey('transaction_uid'),
            "transaction_date" => $request->getInputByKey('transaction_date'),
            "account" => $request->getInputByKey('account'),
            "name" => $request->getInputByKey('name'),
            "amount" => $request->getInputByKey('amount'),
            "payment_destination" => $request->getInputByKey('payment_destination'),
            "inn" => $request->getInputByKey('inn'),
            "bik" => $request->getInputByKey('bik'),
            "kpp" => $request->getInputByKey('kpp'),
            "commission" => $request->getInputByKey('commission'),
            "acquiring_commission" => $request->getInputByKey('acquiring_commission'),
            "acquiring_payment_id" => $request->getInputByKey('acquiring_payment_id'),
            "c2b_qr_code_id" => $request->getInputByKey('c2b_qr_code_id'),
            "body" => $request->all(),
        ]);

        try {
            $targetId = $this->findTarget($moneyboxIn->payment_destination);
            $inn = $request->getInputByKey('inn');
            try {
                $profile = app(FindProfileByIdTask::class)->run($targetId);
                if ($profile->hasAccreditationStatus('accreditation_accredited')) {
                    if ($profile->legal_form->personal->inn === $inn) {
                        $transactionType = 20;
                        $isBeneficiary = true;
                    } else {
                        throw new Exception("ИНН не совпадает");
                    }
                } else {
                    throw new Exception("Профиль не аккредитован");
                }
            } catch (\Throwable $e) {
                try {
                    //TODO проект должен быть на стадии реализации
                    $project = app(FindProjectByIdTask::class)->run($targetId);
                    $profile = $project->profile;
                } catch (\Throwable $e) {
                    throw new Exception("Не найден счет с №" . $targetId);
                }

                if ($profile->legal_form->personal->inn === $inn) {
                    $transactionType = 21;
                    $isBeneficiary = false;
                } else {
                    throw new Exception("ИНН не совпадает");
                }
            }


            $data = app(GenerateUuidAndIdTask::class)->run();
            $request = [
                'uuid' => $data['uuid'],
                'p2p_id' => $data['p2p_id'],
                'transaction_id' => $moneyboxIn->transaction_uid,
                'transaction_type' => $transactionType,
                'amount' => $request->getInputByKey('amount')
            ];

            $client = [
                'is_beneficiary' => $isBeneficiary
            ];

            app(ClientDataSubAction::class)->run($client, $request['uuid'], $profile, 'identification_answer', $isBeneficiary);

            $request['client'] = $client;

            app(SendDataSubAction::class)->run($request['uuid'], config('appSection-moneybox.methods.identification_answer'), $request);

            app(UpdateMoneyboxInTask::class)->run($moneyboxIn->id, [
                "response_code" => 200,
                "response_text" => null,
            ]);

        } catch (\Throwable|Exception $e) {
            app(UpdateMoneyboxInTask::class)->run($moneyboxIn->id, [
                "response_code" => 400,
                "response_text" => $e->getMessage(),
            ]);
        }
    }

    /**
     * @throws Exception
     */
    private function findTarget(string $text): int
    {
        $matches = [];
        $isFind = preg_match("/\d+/", $text, $matches);
        if ($isFind === false) {
            throw new Exception("Не найден идентификатор виртуального счета");
        }

        return $matches[0];
    }
}
